<template>
  <div class="word-training-outer">
    <el-row justify="center" align="middle" style="height: 100vh">
      <el-col :span="32">
        <el-card class="main-card">
          <div class="word-training">
            <!-- 顶部导航栏 -->
            <div class="word-training__header">
              <div class="header-left">
                <h2 class="word-training__title">智能听写</h2>
                <span class="unit-name">{{ currentUnit?.unitName }}</span>
              </div>
              <el-button @click="handleExit" type="primary" plain>
                <el-icon><Back /></el-icon>
                退出
              </el-button>
            </div>

            <!-- 听写内容 -->
            <div class="word-training__content">
              <div class="word-card">
                <!-- 进度条 -->
                <div class="word-card__progress">
                  <el-progress
                    :percentage="dictationProgress"
                    :format="progressFormat"
                    status="success"
                  />
                  <span class="progress-text">
                    {{
                      currentPhase === 'dictation'
                        ? `${dictationCompletedCount}/${totalWords}`
                        : `${dictationReviewCompletedCount}/${dictationReviewWords.length}`
                    }}
                  </span>
                </div>

                <!-- 第二行：喇叭按钮、输入框 -->
                <div
                  style="
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 16px;
                    margin-bottom: 16px;
                  "
                >
                  <el-button
                    class="sound-btn"
                    circle
                    @click="playWordSound"
                    :icon="Microphone"
                  />
                  <el-input
                    ref="dictationInputRef"
                    v-model="dictationInput"
                    placeholder="请输入单词拼写"
                    @keyup.enter="handleDictationEnter"
                    :status="dictationError ? 'error' : ''"
                    :disabled="dictationReadyForNext"
                    style="width: 240px"
                    autofocus
                  />
                  <el-icon
                    v-if="
                      !dictationError &&
                      dictationInput &&
                      dictationInput.trim().toLowerCase() ===
                        currentWord?.spelling.toLowerCase() &&
                      !dictationReadyForNext
                    "
                    style="color: #67c23a; margin-left: 8px"
                  >
                    <Check />
                  </el-icon>
                  <el-icon
                    v-if="dictationReadyForNext"
                    style="color: #409eff; margin-left: 8px; cursor: pointer"
                    @click="nextDictationWord"
                  >
                    <ArrowRight />
                  </el-icon>
                </div>

                <!-- 第三行：拼写错误时显示答案，拼写正确时显示音标 -->
                <div
                  v-if="dictationShowSpelling"
                  style="text-align: center; margin-bottom: 16px"
                >
                  <template v-if="dictationError">
                    <span
                      v-for="(ch, idx) in currentWord?.spelling.split('')"
                      :key="idx"
                      :style="{
                        color: dictationErrorMap[idx] ? '#f56c6c' : '#303133',
                        fontWeight: dictationErrorMap[idx] ? 'bold' : 'normal',
                        fontSize: '22px',
                        marginRight: '2px',
                      }"
                    >
                      {{ ch }}
                    </span>
                  </template>
                  <template v-else>
                    <span style="font-size: 22px; color: #409eff">{{
                      currentWord?.syllable
                    }}</span>
                  </template>
                </div>
              </div>
            </div>

            <!-- 底部进度信息 -->
            <div class="word-training__footer">
              <div class="progress-info">
                <span>有效时长: {{ formatSeconds(effectiveSeconds) }}</span>
                <span>总时长: {{ formatSeconds(totalStudyTime) }}</span>

                <!-- 听写阶段统计 -->
                <template v-if="currentPhase === 'dictation'">
                  <span>听写完成单词数: {{ dictationCompletedCount }}</span>
                  <span>需要听写的单词总个数: {{ totalWords }}</span>
                  <span>听写正确数: {{ dictationCorrectCount }}</span>
                  <span>听写错误数: {{ dictationErrorCount }}</span>
                  <span class="dictation">听写阶段</span>
                </template>

                <!-- 听写复习阶段统计 -->
                <template v-if="currentPhase === 'dictationReview'">
                  <span
                    >听写复习完成单词数:
                    {{ dictationReviewCompletedCount }}</span
                  >
                  <span
                    >需要听写复习的单词总个数:
                    {{ dictationReviewWords.length }}</span
                  >
                  <span class="dictation-review">听写复习阶段</span>
                </template>
              </div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { useRouter } from 'vue-router'
import TASK_API from '@/api/dcyx/task.api'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Back, Microphone, Check, ArrowRight } from '@element-plus/icons-vue'
import type { WordItem } from '@/api/dcyx/dictation.api'
import { useDcyxDictationStore } from '@/store/modules/dcyx_dictation.store'
import { useDcyxUnitStore } from '@/store/modules/dcyx_unit.store'
import DAILY_TIME_RECORDS_API from '@/api/dcyx/daily-tIme-records.api'

// 阶段类型定义
type DictationPhase = 'dictation' | 'dictationReview' | 'finished'

const router = useRouter()
const dictationStore = useDcyxDictationStore()
const unitStore = useDcyxUnitStore()

// 阶段管理
const currentPhase = ref<DictationPhase>('dictation')

// 单词列表
const wordList = ref<WordItem[]>([])

// 听写阶段相关
const dictationIndex = ref(0)
const dictationCorrectCount = ref(0)
const dictationErrorCount = ref(0)
const dictationInput = ref('')
const dictationError = ref(false)
const dictationErrorMap = ref<boolean[]>([])
const dictationReadyForNext = ref(false)
const dictationShowSpelling = ref(false)
const dictationFirstAttempt = ref<Set<number>>(new Set())
const dictationFailedWordIds = ref<Set<number>>(new Set())

// 听写复习阶段相关
const dictationReviewWords = ref<WordItem[]>([])
const dictationReviewIndex = ref(0)
const dictationReviewCorrectCountRef = ref(0)
const dictationReviewCompletedWordIds = ref<Set<number>>(new Set())
const dictationReivewOnceAttempt = ref(true)

// 时间相关
const effectiveSeconds = ref(0)
const totalStudyTime = ref(0)
const secondTimer = ref<number>()
const totalStudyTimer = ref<number>()

// 有效时长相关
const idleTimer = ref<number>()
const isPaused = ref(false)
const idleLimit = 30 // 30秒无操作
const lastAction = ref(Date.now())
let pausedEffectiveSeconds = 0 // 暂停时的有效时长

// 监听用户操作
const activityEvents = ['mousemove', 'keydown', 'mousedown', 'touchstart']
const resetIdle = () => {
  lastAction.value = Date.now()
  if (isPaused.value) {
    isPaused.value = false
    // 恢复时从暂停时的有效时长继续递增
    effectiveSeconds.value = pausedEffectiveSeconds
    startSecondTimer()
    ElMessageBox.close()
  }
}

const handleIdle = () => {
  if (!isPaused.value) {
    isPaused.value = true
    // 暂停时保存当前有效时长
    pausedEffectiveSeconds = effectiveSeconds.value
    stopSecondTimer()
    ElMessageBox.alert('您已30秒无操作，已暂停计时', '提示', {
      showClose: false,
      closeOnClickModal: false,
      closeOnPressEscape: false,
    })
  }
}

const startIdleTimer = () => {
  if (idleTimer.value) clearInterval(idleTimer.value)
  idleTimer.value = window.setInterval(() => {
    if (Date.now() - lastAction.value > idleLimit * 1000) {
      handleIdle()
    }
  }, 1000)
}

const stopIdleTimer = () => {
  if (idleTimer.value) clearInterval(idleTimer.value)
}

const addActivityListeners = () => {
  activityEvents.forEach((evt) => window.addEventListener(evt, resetIdle))
}
const removeActivityListeners = () => {
  activityEvents.forEach((evt) => window.removeEventListener(evt, resetIdle))
}

// 计算属性
const currentWord = computed(() => {
  switch (currentPhase.value) {
    case 'dictation':
      return wordList.value[dictationIndex.value]
    case 'dictationReview':
      return dictationReviewWords.value[dictationReviewIndex.value]
    default:
      return null
  }
})

const currentUnit = computed(() => unitStore.currentUnit)
const totalWords = computed(() => wordList.value.length)

// 听写阶段进度计算
const dictationCompletedCount = computed(
  () => dictationCorrectCount.value + dictationErrorCount.value,
)

// 听写复习阶段进度计算
const dictationReviewCompletedCount = computed(
  () => dictationReviewCompletedWordIds.value.size,
)

const dictationProgress = computed(() => {
  switch (currentPhase.value) {
    case 'dictation':
      return Math.round(
        (dictationCompletedCount.value / totalWords.value) * 100,
      )
    case 'dictationReview':
      return Math.round(
        (dictationReviewCompletedCount.value /
          dictationReviewWords.value.length) *
          100,
      )
    default:
      return 0
  }
})

// 进度条格式化
const progressFormat = (percentage: number) => `${percentage}%`

// 播放单词发音
const playWordSound = async () => {
  const word = currentWord.value?.spelling
  if (!word) return
  if ((window as any).wordAudio) {
    ;(window as any).wordAudio.pause()
    ;(window as any).wordAudio.currentTime = 0
  }
  try {
    const audioUrl = await dictationStore.playWordAudio(word)
    ;(window as any).wordAudio = new window.Audio(audioUrl)
    ;((window as any).wordAudio as HTMLAudioElement).play()
  } catch {
    ElMessage.error('播放音频失败')
  }
}

// 处理退出：先 Gate 检查，未完成则回任务页
const handleExit = async () => {
  try {
    const gate = await TASK_API.getGateTodayStatus()
    const hasPending = !!gate?.hasPending
    localStorage.setItem('GATE_TODAY_STATUS', String(hasPending))
    localStorage.setItem('GATE_TODAY_STATUS_TS', String(Date.now()))
    if (hasPending) {
      router.replace('/gate/tasks')
      return
    }
  } catch { /* ignore */ }
  router.push('/work/word-training')
}

// 听写阶段：输入框自动聚焦
const dictationInputRef = ref<HTMLInputElement | null>(null)
const focusDictationInput = () => {
  nextTick(() => {
    dictationInputRef.value?.focus()
  })
}

// 快捷键处理
const handleKeydown = (e: KeyboardEvent) => {
  if (
    currentPhase.value === 'dictation' ||
    currentPhase.value === 'dictationReview'
  ) {
    if (e.key === 'Enter') {
      handleDictationEnter()
    }
    return
  }
  // 如果是空格，再次播放音频
  // if (e.key === ' ') {
  //   playWordSound()
  // }
}

// 监听输入变化
watch(dictationInput, (val) => {
  if (val) {
    dictationShowSpelling.value = false
  }
})

// 听写阶段：处理输入
const handleDictationEnter = async () => {
  if (dictationReadyForNext.value) {
    nextDictationWord()
    return
  }

  if (!dictationInput.value || !currentWord.value) return

  const wordId = Number(currentWord.value.id)
  const isCorrect =
    dictationInput.value.trim().toLowerCase() ===
    currentWord.value.spelling.toLowerCase()
  const isFirstAttempt = !dictationFirstAttempt.value.has(wordId)
  const isOnceAttemp = dictationReivewOnceAttempt.value
  if (isCorrect) {
    // 拼写正确
    dictationError.value = false
    dictationShowSpelling.value = true
    dictationReadyForNext.value = true

    if (isFirstAttempt) {
      // 首次拼写正确
      if (currentPhase.value === 'dictation') {
        dictationCorrectCount.value++
        try {
          await dictationStore.updateDictationRecord({
            wordId,
            status: 1,
            source: 'zntx',
            sourceFrom: 'zntx',
          })
        } catch {
          ElMessage.error('保存记录失败')
        }
      } else if (currentPhase.value === 'dictationReview') {
        // 在听写复习阶段，我们需要手动跟踪正确的数量
        dictationReviewCorrectCountRef.value++
        dictationReviewCompletedWordIds.value.add(wordId)
      }
    }

    // 一次拼写正确
    if (isOnceAttemp) {
      if (currentPhase.value === 'dictationReview') {
        // 在听写复习阶段，我们需要手动跟踪正确的数量
        dictationReviewCorrectCountRef.value++
        dictationReviewCompletedWordIds.value.add(wordId)
      }
    }
  } else {
    // 拼写错误
    dictationError.value = true
    dictationShowSpelling.value = true
    dictationFirstAttempt.value.add(wordId)

    if (isFirstAttempt) {
      // 首次拼写错误
      if (currentPhase.value === 'dictation') {
        dictationErrorCount.value++
        dictationFailedWordIds.value.add(wordId)
        try {
          await dictationStore.updateDictationRecord({
            wordId,
            status: 0,
            source: 'zntx',
            sourceFrom: 'zntx',
          })
        } catch {
          ElMessage.error('保存记录失败')
        }
      }
    }

    // 生成错误高亮map
    const inputArr = dictationInput.value.trim().split('')
    const answerArr = currentWord.value.spelling.split('')
    const errorArr: boolean[] = []
    for (let i = 0; i < answerArr.length; i++) {
      errorArr.push(inputArr[i]?.toLowerCase() !== answerArr[i].toLowerCase())
    }
    dictationErrorMap.value = errorArr
  }

  playWordSound()
  dictationReivewOnceAttempt.value = false
}

// 听写阶段：下一个单词
const nextDictationWord = () => {
  if (currentPhase.value === 'dictation') {
    if (dictationIndex.value < totalWords.value - 1) {
      dictationIndex.value++
      dictationInput.value = ''
      dictationError.value = false
      dictationErrorMap.value = []
      dictationShowSpelling.value = false
      dictationReadyForNext.value = false
      playWordSound()
      focusDictationInput()
    } else {
      // 听写阶段完成，检查是否需要听写复习
      if (dictationFailedWordIds.value.size > 0) {
        enterDictationReviewPhase()
      } else {
        finishDictation()
      }
    }
  } else if (currentPhase.value === 'dictationReview') {
    // 判断如果完成听写复习的单词id集合个数等于需要听写复习的单词id集合个数，则进入结束阶段
    if (
      dictationReviewCompletedWordIds.value.size ===
      dictationFailedWordIds.value.size
    ) {
      // 听写复习完成
      finishDictation()
      return
    }

    // 筛选出在需要听写复习的单词id集合的，但是不在完成听写复习的单词id集合的单词id
    const remainingWordIds = new Set<number>()
    dictationFailedWordIds.value.forEach((wordId) => {
      // 检查这个单词是否还没有被正确拼写过
      if (!dictationReviewCompletedWordIds.value.has(wordId)) {
        remainingWordIds.add(wordId)
      }
    })

    // 随机选出一个单词id
    const remainingWordIdsArray = Array.from(remainingWordIds)
    const randomIndex = Math.floor(Math.random() * remainingWordIdsArray.length)
    const selectedWordId = remainingWordIdsArray[randomIndex]

    // 从需要听写复习的单词列表中选出该单词，作为下一个需要听写复习的单词
    const selectedWordIndex = dictationReviewWords.value.findIndex(
      (word) => Number(word.id) === selectedWordId,
    )

    if (selectedWordIndex !== -1) {
      dictationReviewIndex.value = selectedWordIndex
      dictationInput.value = ''
      dictationError.value = false
      dictationErrorMap.value = []
      dictationShowSpelling.value = false
      dictationReadyForNext.value = false
      playWordSound()
      focusDictationInput()
      dictationReivewOnceAttempt.value = true
    } else {
      // 如果找不到对应的单词，完成学习
      finishDictation()
    }
  }
}

// 进入听写复习阶段
const enterDictationReviewPhase = () => {
  currentPhase.value = 'dictationReview'
  dictationReviewWords.value = wordList.value.filter((word) =>
    dictationFailedWordIds.value.has(Number(word.id)),
  )
  dictationReviewIndex.value = 0
  dictationReviewCorrectCountRef.value = 0 // Reset correct count for review phase
  dictationReviewCompletedWordIds.value.clear() // Reset completed word ids
  dictationInput.value = ''
  dictationError.value = false
  dictationErrorMap.value = []
  dictationShowSpelling.value = false
  dictationReadyForNext.value = false

  playWordSound()
  focusDictationInput()
}

// 完成听写
const finishDictation = async () => {
  currentPhase.value = 'finished'

  const score = Math.round(
    (dictationCorrectCount.value / totalWords.value) * 100,
  )

  try {
    await dictationStore.updateUnitDictationStatus({
      unitId: Number(currentUnit.value?.unitId) || 0,
      source: 1,
      dictationCompleted: 1,
      dictationScore: score,
      dictationTimeConsuming: totalStudyTime.value,
    })
    await dictationStore.updateUnitDictationStats({
      unitId: Number(currentUnit.value?.unitId) || 0,
      unitTotal: totalWords.value,
      studyNumZntx: dictationCorrectCount.value,
      testTimeZntx: totalStudyTime.value,
      restudyNumZntx: dictationErrorCount.value,
      isEndZntx: 1,
    })

    ElMessage.success(`听写完成！得分：${score}分`)
    // 学习完成后的轻量引导：刷新任务并根据 Gate 状态返回
    try {
      const lastId = Number(localStorage.getItem('LAST_TASK_ITEM_ID') || '0')
      if (lastId > 0) {
        await TASK_API.refreshItem(lastId)
      }
    } catch { /* ignore */ }
    try {
      const gate = await TASK_API.getGateTodayStatus()
      const hasPending = !!gate?.hasPending
      localStorage.setItem('GATE_TODAY_STATUS', String(hasPending))
      localStorage.setItem('GATE_TODAY_STATUS_TS', String(Date.now()))
      if (hasPending) {
        router.replace('/gate/tasks')
        return
      }
    } catch { /* ignore */ }
    router.push('/work/word-training')
  } catch {
    ElMessage.error('保存学习状态失败')
  }
}

// 时间相关函数
const formatSeconds = (s: number) => {
  const h = Math.floor(s / 3600)
  const m = Math.floor((s % 3600) / 60)
  const sec = s % 60
  return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`
}

const startSecondTimer = () => {
  if (secondTimer.value) clearInterval(secondTimer.value)
  secondTimer.value = window.setInterval(() => {
    if (!isPaused.value) {
      effectiveSeconds.value++
      // 每60秒上报一次有效时长
      if (effectiveSeconds.value % 60 === 0) {
        reportEffectiveSeconds()
      }
    }
  }, 1000)
}

const stopSecondTimer = () => {
  if (secondTimer.value) clearInterval(secondTimer.value)
}

// 上报有效时长API
const reportEffectiveSeconds = async () => {
  try {
    await DAILY_TIME_RECORDS_API.addOnlineOrEffectiveSeconds({
      effectiveSeconds: 60,
      onlineSeconds: 0,
    })
    // 上报后查一次最新有效时长
    const res = await DAILY_TIME_RECORDS_API.getTodayOnlineSeconds()
    if (res?.effectiveSeconds != null) {
      effectiveSeconds.value = res.effectiveSeconds
    }
  } catch {
    /* ignore */
  }
}

const startTotalStudyTimer = () => {
  if (totalStudyTimer.value) clearInterval(totalStudyTimer.value)
  totalStudyTimer.value = window.setInterval(() => {
    totalStudyTime.value++
  }, 1000)
}

const stopTotalStudyTimer = () => {
  if (totalStudyTimer.value) clearInterval(totalStudyTimer.value)
}

// 组件挂载
onMounted(async () => {
  try {
    const unit = await unitStore.getCurrentUnit()
    if (!unit?.unitId) {
      ElMessage.error('未找到当前单元信息')
      return
    }

    await dictationStore.fetchDictationWords(unit.unitId)
    wordList.value = dictationStore.wordList

    if (wordList.value.length === 0) {
      ElMessage.warning('当前单元没有单词')
      return
    }

    // 显示新单词时播放读音
    playWordSound()

    // 启动暂停有效时间计算
    addActivityListeners()
    startIdleTimer()
    startSecondTimer() // 启动每秒自增
    startTotalStudyTimer() // 启动总时间计时器
    window.addEventListener('keydown', handleKeydown)
    // 仅首次进入时获取今日有效时长
    try {
      const res = await DAILY_TIME_RECORDS_API.getTodayOnlineSeconds()
      if (res?.effectiveSeconds != null) {
        effectiveSeconds.value = res.effectiveSeconds
      }
    } catch {
      /* ignore */
    }

    // 聚焦输入框
    focusDictationInput()
  } catch {
    ElMessage.error('加载单词失败')
  }
})

// 组件卸载
onUnmounted(() => {
  removeActivityListeners()
  stopIdleTimer()
  stopSecondTimer() // 停止每秒自增
  stopTotalStudyTimer() // 停止总时间计时器
  window.removeEventListener('keydown', handleKeydown)
})
</script>

<style lang="scss" scoped>
.word-training-outer {
  min-height: 100vh;
  width: 100vw;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--el-bg-color-page);
}

.main-card {
  width: 66vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: stretch;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
}

.word-training {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: 1;
}

.word-training__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;

  .header-left {
    display: flex;
    align-items: center;
    gap: 16px;
  }

  .unit-name {
    font-size: 16px;
    color: var(--el-text-color-secondary);
  }
}

.word-training__title {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.word-training__content {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
}

.word-training__footer {
  margin-top: 24px;
  padding: 16px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);

  .progress-info {
    display: flex;
    justify-content: space-around;
    font-size: 14px;
    color: var(--el-text-color-regular);

    .dictation {
      color: #e6a23c; // 听写阶段 - 黄色
    }

    .dictation-review {
      color: #f0c78a; // 听写复习阶段 - 浅黄色
    }
  }
}

.word-card {
  width: 100%;
  max-width: 600px;
  padding: 32px;
  background-color: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);

  &__progress {
    // display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 24px;

    .progress-text {
      font-size: 14px;
      color: var(--el-text-color-secondary);
    }
  }
}

.sound-btn {
  font-size: 20px;
}
</style>
